home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 286_01 / write.c < prev    next >
Text File  |  1989-05-23  |  7KB  |  205 lines

  1. #include <stdio.h>
  2. #include <gds.h>
  3. #include <prtfont.h>
  4.  
  5. #define ERROR (-1)
  6. #define OK 0
  7.  
  8. /*==============================================================*
  9.  *                                                              *
  10.  *    This file contains 2 public routines:-                    *
  11.  *      writec(x,y,ch,boxw,boxh,option)                         *
  12.  *          write a single character to the current frame       *
  13.  *          using currently selected font                       *
  14.  *                                                              *
  15.  *      WriteStr(option,direction,x,y,str,ox,oy)                *
  16.  *          write a character string to the current frame       *
  17.  *          using currently selected font                       *
  18.  *                                                              *
  19.  *==============================================================*/
  20.  
  21. int (*SPACING_FUNC)(); /* special spacing function used by WriteStr
  22.                           if non-none. See the user's manaul    */
  23.  
  24. writec(x,y,ch,boxw,boxh,option)
  25. register int x,y;
  26. int ch,*boxw,*boxh,option;
  27. {
  28.     char huge *tmpptr;
  29.     struct FONTABLE *tptr;
  30.     int wrtwid,shift,fwid,iw,h,owrtwid,temp,temp1,tmpstyle;
  31.     struct fontspec huge *sp;
  32.  
  33.     x+=ORGX; y+=ORGY;
  34.  
  35.     tptr=&FONTTAB[CURFONT];     /* point to current font table */
  36.     if ((ch < tptr->start) || (ch > tptr->lastchar)) {
  37.         /* . . . . . . . . . . . . . . . . . . . . . . . . . . */
  38.         /* required character code does not exist in this font */
  39.         /* replace with default character                      */
  40.         /* . . . . . . . . . . . . . . . . . . . . . . . . . . */
  41.         ch=tptr->defch;
  42.         *boxw=*boxh=0;
  43.         /* return if default character is not valid too ! */
  44.         if ((ch < tptr->start) || (ch > tptr->lastchar)) return;
  45.     }
  46.  
  47.     if (CURFONT > 0 && (tptr=&FONTTAB[CURFONT])->status==USED) {
  48.  
  49.         /* fint the pixel data address in memory */
  50.         if (tptr->type == 0) { /* optimize when using font in ROM */
  51.             sp=tptr->chinfo;
  52.             tmpptr=tptr->fontaddr + (ch - tptr->start) * sp->height
  53.                              * ((sp->inkwidth+7) >> 3);
  54.         } else if (tptr->type == 1) {
  55.             sp=tptr->chinfo + (temp=(ch - tptr->start));
  56.             tmpptr=tptr->fontaddr + (tptr->szinfo)[temp];
  57.         } else {
  58.             graderror(6,12,tptr->type);
  59.         }
  60.     } else { /* default font of invalid font number */
  61.         /* use system font */
  62.         tmpptr=((char huge *) ROMFONT) + (ch << 3);
  63.         sp = (struct fontspec huge *) &ROMchinfo;
  64.     }
  65.     iw=sp->inkwidth;    /* load ink-width  */
  66.     temp=h=sp->height;  /* load ink-height */
  67.     fwid=(iw+7)>>3;     /* width in byte */
  68.     *boxh=sp->cellheight; /* box width */
  69.     *boxw = sp->width;    /* box height */
  70.     switch (option & 0x07) {    /* see the user's manaul */
  71.     case 2:     y += *boxh;
  72.     case 1:     x -= *boxw;
  73.                 break;
  74.     case 6:     x -= (*boxw - 1) >> 1;
  75.     case 3:     y += *boxh;
  76.                 break;
  77.     case 5:     y += (*boxh - 1) >> 1;
  78.     case 4:     x -= (*boxw - 1) >> 1;
  79.                 break;
  80.     case 7:     y += (*boxh - 1) >> 1;
  81.     case 0:     break;
  82.     }
  83.     shift=CUR_PLOT;             /* remember current plot type */
  84.     switch ((option & 0x30) >> 4) { /* see the use's manual */
  85.     case 1:
  86.         owrtwid=1;
  87.         goto drawbox;
  88.     case 2:
  89.         owrtwid=0;
  90.         goto drawbox;
  91.     case 3:
  92.         owrtwid=2;
  93.         if (shift != 2)
  94.             owrtwid=(shift+1) & 0x01;
  95. drawbox:  /* draw block */
  96.         PlotType(owrtwid);
  97.         if (sp->topline < temp - 1)
  98.             temp+=temp-1-sp->topline;
  99.         if ((owrtwid=sp->leftmargin+iw) < *boxw)
  100.             owrtwid=*boxw;
  101.         if (sp->leftmargin < 0) {
  102.             owrtwid-=(temp1=sp->leftmargin);
  103.         } else {
  104.             temp1=0;
  105.         }
  106.         tmpstyle=SetStyle(0xffff);
  107.         HorzLine(x-ORGX+temp1,y-h+1-ORGY,owrtwid,temp);
  108.         SetStyle(tmpstyle);
  109.         PlotType(shift);        /* restore plot type */
  110.     case 0:
  111.         break;
  112.     }
  113.     if ((option & 0x08) || !(iw | h)) {
  114.         /* . . . . . . . . . . . . . . . . . . . . . . .  */
  115.         /*  If width or height is zero or option is set   */
  116.         /*  nothing to write, so return                   */
  117.         /* . . . . . . . . . . . . . . . . . . . . . . .  */
  118.         return;
  119.     }
  120.     x += sp->leftmargin;        /* change x,y to top-left-hand corner */
  121.     y -= sp->topline;           /* of the ink box                     */
  122.  
  123.     /* return if character box is completely outside the window */
  124.     if (x+iw <= WINX1 || x > WINX2 ||
  125.         y+h <= WINY1  || y > WINY2) return;
  126.     shift= x & 0x0f;            /* no. of bits required to shift right */
  127.     owrtwid=(iw+15) >> 4;       /* width in words */
  128.     if (((owrtwid<<4) - iw) < shift) owrtwid++;  /* allocate extra word   */
  129.                                         /* to cater for shift if required */
  130.     if (y < WINY1) {    /* clip top */
  131.         h -= (temp=WINY1-y);
  132.         tmpptr += temp * fwid;
  133.         y = WINY1;
  134.     }
  135.     if ((temp=y+h-1-WINY2) > 0) {  /* clip bottom */
  136.         h -= temp;
  137.     }
  138.     copyfont(fwid,h,owrtwid,tmpptr,CFBUF);      /* copy datat to buffer */
  139.     temp1=0;
  140.     if (x < WINX1) {    /* clip left if required */
  141.         ctextL((temp=WINX1-x),owrtwid,h,h * owrtwid,CFBUF);
  142.         iw -= temp & 0xfff0;
  143.         temp1=((temp & 0x0f)+shift) >> 4;  /* first word of every row in */
  144.                                            /* buffer will be all zero    */
  145.         x = WINX1;
  146.     }
  147.     if ( x+iw-1 > WINX2) {      /* clip right */
  148.         ctextR((iw=WINX2-x+1),owrtwid,h,CFBUF);
  149.     }
  150.     wrtwid=(iw+15) >> 4;
  151.     if (((wrtwid<<4) - iw) < shift) wrtwid++;
  152.  
  153.     /* Finally, ready to write !! */
  154.     wrtc(x,y,shift,wrtwid,h,owrtwid,CFBUF,temp1);
  155. }
  156.  
  157. WriteStr(option,direction,x,y,str,ox,oy)
  158. int option,direction,x,y,ox,oy;
  159. char *str;
  160. {
  161.     int ch,w,h,moveoption;
  162.  
  163.     if ((moveoption=(option>>8) & 0x03) == 2) {
  164.         if (SPACING_FUNC == (int (*)(int *)) NULL) {
  165.             moveoption=1; 
  166.         }
  167.     } 
  168.     while ((ch = *str++)) {
  169.         writec(x,y,ch,&w,&h,(option & 0xff));
  170.         if (moveoption == 0) {
  171.             switch (direction & 0x07) {
  172.             case 0:
  173.             case 7:
  174.             case 1:
  175.                 x += w;
  176.                 break;
  177.             case 3:
  178.             case 4:
  179.             case 5:
  180.                 x -= w;
  181.                 break;
  182.             }
  183.             switch (direction & 0x07) {
  184.             case 1:
  185.             case 2:
  186.             case 3:
  187.                 y += h;
  188.                 break;
  189.             case 5:
  190.             case 6:
  191.             case 7:
  192.                 y -= h;
  193.                 break;
  194.             }
  195.         } else if (moveoption == 2) {
  196.             if ((*SPACING_FUNC)(&x,&y,w,h,str)) break;
  197.         }
  198.         x += ox;
  199.         y += oy;
  200.     }
  201. LASTX=x;  /* remember last coordinate */
  202. LASTY=y;
  203. }
  204.  
  205.